1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| #include <cstdio> #include <queue> #include <cstring> const int maxn = 12005; const int INF = 0x3f3f3f3f; using namespace std; struct E{ int to, nxt, f; }e[maxn << 1]; int head[maxn], tot = 1; void addedge(int u, int v, int f){ e[++tot].to = v, e[tot].nxt = head[u], e[tot].f = f; head[u] = tot; } void ins(int u, int v, int f){ addedge(u, v, f); addedge(v, u, 0); } int dep[maxn], now[maxn], T; bool bfs(){ queue <int> q; while (!q.empty()) q.pop(); q.push(0); memset(dep, 0, sizeof dep); dep[0] = 1; memcpy(now, head, sizeof now); while (!q.empty()){ int cur = q.front(); q.pop(); for (int i = head[cur]; i; i = e[i].nxt) if (!dep[e[i].to] && e[i].f){ dep[e[i].to] = dep[cur] + 1; q.push(e[i].to); } } return dep[T]; } int upper[maxn]; int dfs(int cur, int Max){ if (cur == T) return Max; int flow = 0; for (int i = now[cur]; i; i = e[i].nxt){ now[cur] = i; if (flow >= Max) return flow; if (dep[e[i].to] == dep[cur] + 1 && e[i].f){ int tmp = dfs(e[i].to, min(Max - flow, e[i].f)); if (tmp == 0) continue; e[i].f -= tmp; e[i ^ 1].f += tmp; flow += tmp; } } return flow; } int maxflow = 0; void Dinic(){ while (bfs()) maxflow += dfs(0, INF); } int n, m, res[maxn], last[maxn]; bool vis[maxn]; int main(){ scanf("%d%d", &n, &m); for (int u, v, i = 1; i <= m; i++){ scanf("%d%d", &u, &v); ins(u << 1, v << 1 | 1, 1); } T = n * 2 + 2; for (int i = 1; i <= n; i++) ins(0, i << 1, 1), ins(i << 1 | 1, T, 1), last[i] = tot - 1; Dinic(); int ans = n - maxflow; for (int i = 1; i <= n; i++){ if (vis[i] || e[last[i]].f == 0) continue; int cur = i << 1; while (1){ vis[cur >> 1] = 1; bool f = 0; printf("%d ", cur >> 1); for (int j = head[cur]; j; j = e[j].nxt) if (e[j].f == 0 && e[j].to != 0) f = 1, cur = e[j].to - 1; if (!f) break; } puts(""); } printf("%d\n", ans); return 0; }
|